﻿//=====================================================================================================
// LocalizationLibrary
// The Localization Library is a collection of reusable software components that provide 
// support for localization. This library enables you to localize WPF, Silverlight and WP7 applications.
// (http://localizationlibrary.codeplex.com)
//=====================================================================================================
// Author: Nicola Gallo (Website: www.nicola.gallo.name, Email: nicolagmt@hotmail.it) 
//=====================================================================================================

namespace ReflectionStudio.LocalizationLibrary.Threading
{
    //.NET References
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using ReflectionStudio.Core.Events;
    /// <summary>
    /// Implements a localization's job.
    /// </summary>
    internal class LocalizationJob
    {
        //Constructs

        /// <summary>
        /// Creates a new instance of <see cref="LocalizationJob"/> class.
        /// </summary>
        /// <param name="token"></param>
        /// <exception cref="ArgumentNullException">
        /// Thrown whether <paramref name="resourceType"/> parameter is null.
        /// </exception>
        public LocalizationJob(DynamicResourceToken token)
        {
            if (token == null)
            {
                throw new ArgumentNullException("Token parameter shouldn't be null.");
            }
            this.Token = token;
        }

        //Properties

        /// <summary>
        /// Gets the localization provider.
        /// </summary>
        private LocalizationProvider LocalizationProvider { get; set; }

        /// <summary>
        /// Gets the token.
        /// </summary>
        public DynamicResourceToken Token { get; private set; }

        /// <summary>
        /// Called when the <see cref="LocalizationProvider"/> has completed the localization.
        /// </summary>
        public LocalizationCompletionCallback OnLocalization { get; set; }

        /// <summary>
        /// Gets true if the worker is working, false otherwise.
        /// </summary>
        public bool IsStarted { get; private set; }

        /// <summary>
        /// Gets the thread that is localizing the token.
        /// </summary>
        public Thread Thread { get; private set; }

        //Methods

        /// <summary>
        /// Start the worker.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown whether the localization's job has already been started.
        /// </exception>
        public void Start()
        {
            if (this.IsStarted)
            {
                throw new InvalidOperationException("The localization's job has already been started.");
            }
            this.Thread = new Thread(this.OnStart);
            this.Thread.Start();
            this.IsStarted = true;
        }

        /// <summary>
        /// Called when thread is started.
        /// </summary>
        private void OnStart()
        {
            Type locProvType = LocalizationManager.AppLocalizationProviderType;
            if (locProvType != null)
            {
                this.LocalizationProvider = (LocalizationProvider)Activator.CreateInstance(locProvType,
                    new Object[] { this.Token, this.OnLocalization });
                bool raisedException = false;
                try
                {
                    this.LocalizationProvider.Localize();
                }
                catch (Exception ex)
                {
                    raisedException = true;
                    String message = String.Format("Exception occurred during the localization. ResourceId: {0} ExceptionMassge: {1}.",
                        this.Token.ResourceID, ex.Message);
                    Tracer.Verbose("LocalizationManager.RegisterAssembly", message);
                }
                finally
                {
                    if (raisedException)
                    {
                        this.LocalizationProvider.PublishOnLocalization();
                    }
                }
            }
        }     

        /// <summary>
        /// Aborts the job.
        /// </summary>
        public void Abort()
        {
            if ((this.Thread != null) && (this.Thread.IsAlive))
            {
                try
                {
                    this.Thread.Abort();
                }
                catch { }
            }
        }
    }
}